April 18, 2021
프로그래머스 월간 코드 챌린지 시즌2 4월 3번 문제로 출제되었다
주어진 노드들의 값을 모두 0으로 만들어야 한다.
다른 언어들은 재귀를 이용한 DFS로 쓱싹 해결이 가능한데 JS는 Call Stack이 얕아 런타임 에러가 났다.
어쩔 수 없이 스택을 이용한 DFS로 해결하였다.(파이썬으로 풀면 스택 사이즈 조절이 가능하다.)
정답을 BigInt로 처리해야 한다.(다른 언어라면 long long 등)
기본적인 아이디어는 말단 노드에서부터 0으로 값을 만들어가는데 있다.
문제 설명에서는 한번씩 연산이 수행되는 것으로 나왔지만 그럴 필요는 없다.
-1
을 반환한다if (arr.reduce((a, b) => a + b) !== 0) return -1
dfs를 위한 visited와 stack도 선언한다.
const tree = new Array(arr.length).fill(0).map(() => new Array())
const nums = arr.slice()
let result = BigInt(0)
edges.forEach(([a, b]) => {
tree[a].push(b)
tree[b].push(a)
})
const visited = new Array(arr.length).fill(false)
const stack = [[0, null]]
stack
에 들어가게 되고 Bottom-up 방식으로 dfs가 수행된다.while (stack.length) {
const [curr, parent] = stack.pop()
if (visited[curr]) {
result += BigInt(Math.abs(nums[curr]))
nums[parent] += nums[curr]
nums[curr] = 0
continue
}
visited[curr] = true
stack.push([curr, parent])
for (const next of tree[curr]) {
if (!visited[next]) stack.push([next, curr])
}
}
return result
if (visited[curr]) {
result += BigInt(Math.abs(nums[curr]))
nums[parent] += nums[curr]
nums[curr] = 0
continue
}
function solution(arr, edges) {
if (arr.reduce((a, b) => a + b) !== 0) return -1
const tree = new Array(arr.length).fill(0).map(() => new Array())
const nums = arr.slice()
let result = BigInt(0)
edges.forEach(([a, b]) => {
tree[a].push(b)
tree[b].push(a)
})
const visited = new Array(arr.length).fill(false)
const stack = [[0, null]]
while (stack.length) {
const [curr, parent] = stack.pop()
if (visited[curr]) {
result += BigInt(Math.abs(nums[curr]))
nums[parent] += nums[curr]
nums[curr] = 0
continue
}
visited[curr] = true
stack.push([curr, parent])
for (const next of tree[curr]) {
if (!visited[next]) stack.push([next, curr])
}
}
return result
}